/*
	Description: A shared memory segment is "allocated", i.e.: a request is
	sent to the operating system to get a chunk of physical memory (out of 
	the current process virtual memory space). We need a "key" value (an 		integer) to name such a memory segment. Any process wanting to access 
	that memory chunk has to know what the "key" is. In this example an 
	arbitrarily chosen number is assigned as the key.

	Author: Hugo Mendez @ ITESM CCV Sep 2011
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <string.h>

int main (int argc, const char * argv[]) {
    int key=3456; //number to identify my shared memory segment
 int pageSize= getpagesize();  //how big is the size of a page memory in my system?
  //Let's allocate a memory segment to share with the world (one page of memory)
  //We'll get a unique memory segment identifier
  int segment_id = shmget(key, pageSize, IPC_CREAT| IPC_EXCL | 0666); //everybody can read and write
  
  //Check for problems
  if(segment_id < 0){
    printf("Problemas al solicitar el segmento de memoria");
    exit(1);
  }
  printf("segment_id: %d\n", segment_id);
  
  //Now we have a segment, it is actually floating, to use it, every single process has to
  //attach it to its "virtual memory space", even the process that allocated it
  //Let's do it for this process (the parent process)
  char *shm;      //We need a byte pointer to have access to the shared memory
  
  //Let Linux choose an available space within our virtual memory space (that's the NULL)
  shm = shmat(segment_id, NULL, 0);
  //shm "points" to what we can see as an array of memory locations
  
  //Let's write something into this "shared array"
  strcpy(shm, "Hola mundo");
  
  /*
     * Finally, we wait until the other process
     * changes the first character of our memory
     * to '*', indicating that it has read what
     * we placed in there.
     */
    while (*shm != '*')
        sleep(1);
  
  //If we are done, detach the memory segment
  shmdt (shm);
  
  //We need to liberate the memory segment, otherwise it remains allocated
  //The segment is removed when the last process that has attached it finally detaches it.
  shmctl (segment_id, IPC_RMID, NULL);
  return 0;
}

/*
 Reference links:
 http://www.cs.cf.ac.uk/Dave/C/node27.html
 http://developer.apple.com/library/ios/#documentation/System/Conceptual/ManPages_iPhoneOS/man2/stat.2.html
 http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.genprogc/doc/genprogc/create_shared_mem_wshmat.htm
 http://beej.us/guide/bgipc/output/html/multipage/shm.html
 
 */

